/*
 * Copyright (C) 2005-2007 Oleh Hapon ohapon@users.sourceforge.net
 * 
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * 
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307, USA.
 * 
 * Oleh Hapon
 * Kyiv, UKRAINE
 * ohapon@users.sourceforge.net
 */
/*
 * Created on 15.11.2003
 *
 */
package com.deruan.hotcore.util;


import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Locale;
import java.util.Properties;
import java.util.Collection;
import java.util.PropertyResourceBundle;
import java.util.ResourceBundle;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.InputStream;
import java.io.IOException;
import java.io.FileInputStream;

import com.deruan.hotcore.util.StringUtilities;
import com.deruan.hotcore.util.SystemInfo;

/**
 * Application environment
 * 
 * @author Oleh Hapon
 * $Id$
 */
public class AppEnvironment {
    
    /** Root dir property **/
    public static final String ROOT_DIR_PROPERTY          = "plazma.platform.dir";

    /** Configuration dir property **/
    public static final String CONFIGURATION_DIR_PROPERTY = "plazma.platform.configuration.dir";


    /** UI conf property **/
    public static final String UI_CONF_PROPERTY = "plazma.platform.ui.conf";
    

    /** Demo property **/
    public static final String DEMO_PROPERTY              = "plazma.platform.demo";

    /** Auto login property **/
    public static final String AUTO_LOGIN_PROPERTY        = "plazma.platform.autologin";
    
    /** Input Dialog property **/
    public static final String INPUT_DIALOG_PROPERTY        = "plazma.platform.inputdialog";
    
    
	
    /** Configuration name property. It is name of folder. Example: conf, conf-server, conf-explorer etc. **/
    public static final String CONFIG_NAME_PROPERTY       = "plazma.conf.name";	
	
    /** Configuration prefix of file name. Example: server.file-config.xml **/
    public static final String CONFIG_PREFIX_PROPERTY     = "plazma.conf.prefix";
	
	
	
	
    /** File separator **/
    public static final String FILE_SEPARATOR             = System.getProperty("file.separator");

    /** User dir **/
    public static final String USER_DIR                   = System.getProperty("user.dir");

    /** Default configuration name **/
    public static final String DEFAULT_CONFIG_NAME        = "conf";
    
    /** Default logs folder **/
    public static final String DEFAULT_LOGS_DIR_NAME      = "logs";    

	
    /** Default root property file name **/
    public static final String DEFAULT_ROOT_PROPERTY_FILE = "plazma.properties";

    /** Default application config file **/
    public static final String DEFAULT_APPLICATION_CONFIG_FILE = "application.xml";
    
    /** Default system configuration file name **/
    public static final String DEFAULT_SYSTEM_CONFIG_FILE = "system-config.xml";
	

    public static final String STD_OUT = "std.out";
    
    public static final String STD_ERR = "std.err";
    

    public static final String DEFAULT_USER_INTERFACE = "All";
    

    
    public static final String SERVER_CONF_FILE = "server.conf";
    
    public static final String CLIENT_CONF_FILE = "client.conf";    
	
    protected static Properties properties;

    protected static String rootDir;
	
    protected static String configurationDir;
    
    protected static String confName;
	
    protected static String confPrefix;
    
    protected static String systemConf;
    
    protected static String uiConf;
    
    protected static String logsDirName;    

    protected static boolean externalConfigFile;
	
    protected static boolean externalDatabaseConfigFile;

    protected static String applicationManagerClass;
    
    
    protected static boolean demo;
    
    protected static boolean autoLogin;    
    
    protected static boolean inputDialog;    
	
    
    private static String applicationConfigFile;
    
    private static String systemConfigFile;
    
    private static String userInterface;
    
    // server, client, standalone
    private static String appType;
    
    static {
		
        initSystemProperties();
		
        rootDir = System.getProperty(ROOT_DIR_PROPERTY, USER_DIR);
        
	confName = System.getProperty(CONFIG_NAME_PROPERTY, DEFAULT_CONFIG_NAME);
	confPrefix = System.getProperty(CONFIG_PREFIX_PROPERTY, "");
	
	configurationDir = System.getProperty(CONFIGURATION_DIR_PROPERTY, rootDir);
	
	systemConf = System.getProperty("plazma.platform.system.conf", "");
	uiConf = System.getProperty(UI_CONF_PROPERTY, "");
	
	applicationConfigFile = System.getProperty("plazma.platform.application.config.file", DEFAULT_APPLICATION_CONFIG_FILE);
	systemConfigFile = System.getProperty("plazma.platform.system.config.file", DEFAULT_SYSTEM_CONFIG_FILE);
	
	if (!StringUtilities.isEmpty(systemConf)) {
	    applicationConfigFile = systemConf + "/" + applicationConfigFile;
	    systemConfigFile = systemConf + "/" + systemConfigFile;
	}
	    
        demo = Boolean.valueOf(System.getProperty(DEMO_PROPERTY, "false")).booleanValue();
        autoLogin = Boolean.valueOf(System.getProperty(AUTO_LOGIN_PROPERTY, "false")).booleanValue();
        inputDialog = Boolean.valueOf(System.getProperty(INPUT_DIALOG_PROPERTY, "true")).booleanValue();
        
	logsDirName = DEFAULT_LOGS_DIR_NAME;        
	
        externalConfigFile = false;
        externalDatabaseConfigFile = false;
        properties = new Properties();
        
        initApplicationType();
    }

    /**
     * Initialize system properties.
     * 
     * Load properties from file <user.dir>/plazma.properties.
     * Set properties ( System.setProperty(key, value) ) 
     */
    private static void initSystemProperties() {
	try {
	    String rootPropertyFile = USER_DIR + FILE_SEPARATOR + DEFAULT_ROOT_PROPERTY_FILE;
	    if (!isFileExist(rootPropertyFile)) {
		return;
	    }
	    if (SystemInfo.isWindows) {
		 fixingPropertiesFile(rootPropertyFile);
	    }
	    Properties props = new Properties();
	    props.load(new FileInputStream(rootPropertyFile));
	    Enumeration enums = props.keys();
	    Replacer[] replacers = createReplacers();
	    
	    while (enums.hasMoreElements()) {
		String key = (String) enums.nextElement();
		String value = props.getProperty(key);
		String replValue = replaceValue(replacers, value);
		System.out.println("KEY = " + key +", VALUE = " + replValue);
		System.setProperty(key, replValue);
	    }

	} catch (IOException ex) {
	    ex.printStackTrace();
	}

    }
    
    private static void initApplicationType() {
	appType = null;
	String rootDir = getRootDir();
	String fileName = rootDir + "/" + SERVER_CONF_FILE;
	File file = new File(fileName);
	if (file.exists()) {
	    appType = "server";
	    return;
	}
	fileName = rootDir + "/" + CLIENT_CONF_FILE;
	file = new File(fileName);
	if (file.exists()) {
	    appType = "client";
	    return;
	}
    }
    
    //
    
    private static class Replacer {
	String from;

	String to;
    }

    private static Replacer[] createReplacers() {

	Replacer[] replacer = new Replacer[4];

	String userDir = USER_DIR;
	//String rootDir = AppEnvironment.getRootDir();
	String parentUserDir = getParentDir(userDir);
	//String parentRootDir = getParentDir(rootDir);
	
	replacer[0] = new Replacer();
	replacer[0].from = "${user.dir}";
	replacer[0].to = userDir;
	
	replacer[1] = new Replacer();
	replacer[1].from = "${parent.user.dir}";
	replacer[1].to = parentUserDir;
	
	replacer[2] = new Replacer();
	replacer[2].from = "../";
	replacer[2].to = parentUserDir + FILE_SEPARATOR;
	
	replacer[3] = new Replacer();
	replacer[3].from = "..\\";
	replacer[3].to = parentUserDir + FILE_SEPARATOR;

	//replacer[1] = new Replacer();
	//replacer[1].from = "${root.dir}";
	//replacer[1].to = rootDir;

	//replacer[2] = new Replacer();
	//replacer[2].from = "${plazma.platform.dir}";
	//replacer[2].to = rootDir;

	
	
	// Parent dir
	
	

	//replacer[4] = new Replacer();
	//replacer[4].from = "${parent.root.dir}";
	//replacer[4].to = parentRootDir;

	//replacer[5] = new Replacer();
	//replacer[5].from = "${parent.plazma.platform.dir}";
	//replacer[5].to = parentRootDir;
	
	
	return replacer;
    }

    private static String getParentDir(String dir) {
	if (dir == null) {
	    return null;
	}
	int index = dir.lastIndexOf(File.separator);
	if (index < 0) {
	    return dir;
	}
	return dir.substring(0, index);
    }
    
    
    private static String replaceValue(Replacer[] replacer, String value) {
	String val = value;
	for (int i = 0; i < replacer.length; i++) {
	    val = replaceAll(val, replacer[i].from, replacer[i].to);
	}
	return val;
    }
    
    
    private static String replaceAll(String str, String s1, String s2) {
	return StringUtilities.replaceAll(str, s1, s2);
    }
    
    
    //
    private static void fixingPropertiesFile(String fileName) {
	BufferedReader reader = null;
	BufferedWriter writer = null;
	try {
	    reader = new BufferedReader(new FileReader(fileName));
	    String str = null;

	    ArrayList<String> buff = new ArrayList<String>();
	    boolean isReplace = false;
	    while ((str = reader.readLine()) != null) {
		if (str.startsWith(ROOT_DIR_PROPERTY)) {
		    str = str.replace("\\", "/");
		    isReplace = true;
		}
		buff.add(str);
	    }

	    reader.close();
	    reader = null;

	    if (buff.size() == 0 || !isReplace) {
		return;
	    }

	    writer = new BufferedWriter(new FileWriter(fileName));

	    for (String line : buff) {
		writer.write(line + '\n');
	    }

	    writer.close();
	    writer = null;
	    System.out.println(fileName + " file was fixed");
	} catch (Exception ex) {
	    ex.printStackTrace();
	} finally {
	    try {
		if (reader != null) {
		    reader.close();
		}
		if (reader != null) {
		    reader.close();
		}

	    } catch (IOException ex) {
		//
	    }

	}

    }

    public static void init() {
	// Stub
    }

    public static String getProperty(String key) {
	return properties.getProperty(key);
    }

    public static void setProperty(String key, Object value) {
	properties.put(key, value);
    }

    public static void setRootDir(String dir) {
	if (dir == null)
	    rootDir = "";
	else
	    rootDir = dir;
    }

	
    public static Properties getProperties() {
	return properties;
    }

    public static void setProperties(Properties properties) {
	AppEnvironment.properties = properties;
    }

    public static String getRootDir() {
	return rootDir;
    }

    
    public static String getConfigurationDir() {
	return configurationDir;
    }
    
    public static String getConfName() {
	return confName;
    }

    public static String getConfPrefix() {
	return confPrefix;
    }

  
    public static String getSystemConf() {
	return systemConf;
    }
    
    public static String getUIConf() {
	return uiConf;
    }
    

    public static void setExternalConfigFile(boolean externalConfigFile) {
	AppEnvironment.externalConfigFile = externalConfigFile;
    }

    public static boolean isExternalDatabaseConfigFile() {
	return externalDatabaseConfigFile;
    }   

    public static boolean isFileExist(String fileName) {
    	return new File(fileName).exists();
    }


    public static String getRootConfigFileName(String name) {
        return getConfigurationDir() + FILE_SEPARATOR + getConfName() + FILE_SEPARATOR + getConfPrefix() + name;
    }
    
    /*
    public static String getConfigDir() {
        return getConfigurationDir() + FILE_SEPARATOR + getConfName() + FILE_SEPARATOR + getConfPrefix();
    }
    */
    
    public static String getLogsDir() {
        return getRootDir() + FILE_SEPARATOR + getLogsDirName();
    }
    
    public static String getLogsDirName() {
	return logsDirName;
    }


    public static String getAbsoluteConfigFileName(String name) {
        if (name == null) return name;
        if (true) {
            return getRootConfigFileName(name);
        } else {
            return name;
        }
    }
    
     public static void main(String[] args) {
		System.out.println(USER_DIR+"xczcxzczxc");
	}
	
}
